Scripted Test
The book has now been published and the content of this chapter has likely changed substanstially.Please see page 285 of xUnit Test Patterns for the latest information.
Also known as: Hand-Written Test, Hand-Scripted Test, Programatic Test, Automated Unit Test
How do we prepare automated tests for our software?
We automate the tests by writing test programs by hand.
Sketch Scripted Test embedded from Scripted Test.gif
Automated tests serve several purposes. They can be used for regression testing software after it has been changed. They can help document the behavior of the software. They can also be used to specify the behavior of the software before it has been written. How we prepare the automated test scripts affects which purpose they can be used for, how robust they are to changes in the system under test (SUT) and how much skill and effort it takes to prepare them.
Scripted Tests allow us to prepare our tests before the software is developed so they can help drive the design.
How It Works
We automate our tests by writing test programs that interact with the SUT for the purpose of exercising its functionality. Unlike Recorded Tests (page X), these tests can be either customer tests or unit tests. By convention, these test programs are called "test scripts" to distinguish them from the production code they test.
When To Use It
We should use a Scripted Test whenever we are using the automated tests to drive the development of software. Recorded Tests don't serve this need very well because it is difficult to record tests without having an application to record them from. Preparing Scripted Tests takes programming experience as well as experience in testing techniques. It is unlikely that most business users on a project would be interested in learning how to prepare Scripted Tests. An alternative to scripting tests in a programming language is to define a Higher Level Language (see Principles of Test Automation on page X) for testing the SUT and then implementing the language as a Data-Driven Test (page X) Interpreter[GOF]. An open source framework for defining Data-Driven Tests is Fit and its wiki-based cousin, Fitnesse. Canoo WebTest is another tool that supports this style of testing.
If we have an existing legacy application (A system without a safety net of automated tests), we can consider using Recorded Tests as a way of quickly creating a suite of regression tests that will protect us while we refactor the code to introduce testability. Once an application is up and running and we don't expect a lot of changes to it, we can use Recorded Tests to do regression testing.
Implementation Notes
Traditionally, Scripted Tests were written as "test programs" often in a special test scripting language. Nowadays, we prefer to write Scripted Tests using a Test Automation Framework (page X) such as xUnit in the same language as the SUT. In this case, each test program is typically captured in the form of a Test Method (page X) on a Testcase Class (page X). To minimize Manual Intervention (page X), each test method should implement a Self-Checking Test (see Goals of Test Automation on page X) that is also a Repeatable Test (see Goals of Test Automation).
Example: Scripted Test
The following is an example of a Scripted Test written in JUnit:
public void testAddLineItem_quantityOne(){ final BigDecimal BASE_PRICE = UNIT_PRICE; final BigDecimal EXTENDED_PRICE = BASE_PRICE; // Setup Fixture Customer customer = createACustomer(NO_CUST_DISCOUNT); Invoice invoice = createInvoice(customer); // Exercise SUT invoice.addItemQuantity(PRODUCT, QUAN_ONE); // Verify Outcome LineItem expected = createLineItem( QUAN_ONE, NO_CUST_DISCOUNT, EXTENDED_PRICE, PRODUCT, invoice); assertContainsExactlyOneLineItem( invoice, expected ); } public void testChangeQuantity_severalQuantity(){ final int ORIGINAL_QUANTITY = 3; final int NEW_QUANTITY = 5; final BigDecimal BASE_PRICE = UNIT_PRICE.multiply( new BigDecimal(NEW_QUANTITY)); final BigDecimal EXTENDED_PRICE = BASE_PRICE.subtract(BASE_PRICE.multiply( CUST_DISCOUNT_PC.movePointLeft(2))); // Setup Fixture Customer customer = createACustomer(CUST_DISCOUNT_PC); Invoice invoice = createInvoice(customer); Product product = createAProduct( UNIT_PRICE); invoice.addItemQuantity(product, ORIGINAL_QUANTITY); // Exercise SUT invoice.changeQuantityForProduct(product, NEW_QUANTITY); // Verify Outcome LineItem expected = createLineItem( NEW_QUANTITY, CUST_DISCOUNT_PC, EXTENDED_PRICE, PRODUCT, invoice); assertContainsExactlyOneLineItem( invoice, expected ); } Example CamugExampleAdditionalTest embedded from java/com/clrstream/camug/example/test/TestRefactoringExample.java
About the Name
Automated test programs are traditionally called "test scripts". This is probably due to the heritage of such test programs; originally they were implemented in interpreted test scripting languages such as TCL. The downside of calling these tests Scripted Test is that it opens the door to confusion with the kind of script a person would follow during manual testing as opposed to unscripted testing such as exploratory testing.
Further Reading
There are many books written about the process of writing Scripted Tests and using them to drive the design of the SUT. A good place to start would be [TDD-BE] or [TDD-APG].
Copyright © 2003-2008 Gerard Meszaros all rights reserved